package org.fglxy.mockserver.netty;

import java.util.concurrent.TimeUnit;

import org.fglxy.mockserver.mock.IMockEnd;
import org.fglxy.mockserver.netty.dynamic.DynamicProtoDecode;
import org.fglxy.mockserver.netty.dynamic.DynamicProtoEncode;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class NettyClient {
	// 服务器ip
	private String serverIp;
	// 服务器端口
	private int serverPort;
	private Bootstrap boot;
	private EventLoopGroup group;
	// 处理链
	private ChannelInitializer<SocketChannel> handler;

	private Channel channel;

	public NettyClient(String serverIp, int serverPort) {
		this.serverIp = serverIp;
		this.serverPort = serverPort;
	}

	public NettyClient setHandler(ChannelInitializer<SocketChannel> handler) {
		this.handler = handler;
		return this;
	}

	public void start(IMockEnd client) throws InterruptedException {
		this.group = new NioEventLoopGroup();

		this.boot = new Bootstrap();
		this.boot.group(this.group).channel(NioSocketChannel.class); // 使用NioSocketChannel来作为连接用的Channel类
		if (this.handler == null) {
			this.handler = new ChannelInitializer<SocketChannel>() {

				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					ch.pipeline().addLast(new DynamicProtoDecode(client)).addLast(new DynamicProtoEncode());
				}

			};
		}
		this.boot.handler(handler);

		// 发起连接请求
		final ChannelFuture future = this.boot.connect(this.serverIp, this.serverPort).sync();

		this.channel = future.channel();
	}

	public Channel getChannel() {
		return this.channel;
	}

	public void release() {
		if (this.group != null && !this.group.isShutdown()) {
			this.group.shutdownGracefully(0, 2, TimeUnit.SECONDS);
		}
	}
}
